#define F_CPU 11059200

//#define DozwolonaStalaPredkosc
//#define DozwolonaLosowaJazda
#define DozwolonyDuzyTor
//#define DozwolonaGwiazda

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>        // funkcje sei(), cli()
#include <stdlib.h>

#include "buttons.h"
#include "diody.h"
#include "adc.h"
#include "usart.h"
#include "motor.h"
#include "eeprom.h"
#include "opcje.h"
#include "inputs.h"
#include "komunikacja.h"


// 0 Normalny tryb pracy: ADC -> Predkosc i LEDy, Przycisk 1 -> On/Off, Przycisk 2 -> Kierunek
// 1 EEPROM z adresow 0-7 na diody w petli
// 2 Test UART - zapala diody aby wyswietlic binarnie liczbe odebrana z UART
// 3 Test wejsc (INPUTS) - zapala diody zgodnie ze stanem pierwszych 3 wejsc
// 4 Program koncowy
// 5 Zapisanie EEPROMu
// 6 Wykrywanie zera
// 7 Buttony

#define TRYB 4

#ifdef DozwolonyDuzyTor
#include "muzyka.h"
#endif

ISR(BADISR_vect) 
{ 
	//Gdy wyskoczy jakies nieobslugiwane przerwanie (domyslnie uklad sie resetuje)
	LED_Alarm();
} 

int main()
{
	LED_init();
	USART_init();
	MOTOR_init();
	BUTTONS_init();
	INPUTS_init();
	OPCJE_init();
	ADC_init();
	sei();
	ADC_startMeasure();

	_delay_ms(10);

	#ifdef DozwolonyDuzyTor
	TrybPracy = DuzyTor;	//hack
	#endif

	while (1)
	{
	/* ******************** -------- ******************** */
		#if TRYB == 7
			if (STEROWANIE_KOMPUTEREM_ison())
				LED_on(1);
			else
				LED_off(1);
			if (ZEZWOLENIE_ison())
				LED_on(2);
			else
				LED_off(2);
		#endif
	/* ******************** -------- ******************** */
		#if TRYB == 6
			unsigned char licznik = 0;
			unsigned char opoznienie = 1;
			while(1)
			{	
				if (WykryteZero)
				{
					_delay_us(opoznienie*100+2000);
					TRIAK_on();
					++licznik;
					if (licznik == 10)
					{
						LED_Alarm();
						licznik = 0;
						opoznienie++;
					}
					if (opoznienie == 40)
					{
						opoznienie = 0;
					}
					while(WykryteZero){ sleep(); }
					_delay_us(100);
					TRIAK_off();
				}
			}

		#endif
	/* ******************** -------- ******************** */
		#if TRYB == 5
			OPCJE_zapiszTrybPracy(StalaPredkosc);
			OPCJE_zapiszPredkosc(255);
			OPCJE_zapiszKierunek(GOLEFT);
			OPCJE_zapiszZezwolenieNaStart('1');
			OPCJE_zapiszZmianaOpoznienia(60);
			OPCJE_zapiszZmianaOpoznienia(80);
			OPCJE_zapiszCzasJazdy(20);
			OPCJE_zapiszCzasJazdyPlusMinus(10);
			OPCJE_zapiszCzasPostoju(10);
			OPCJE_zapiszCzasPostojuPlusMinus(5);
			while(1){sleep();}
		#endif 

	/* ******************** -------- ******************** */
		#if TRYB == 4
			switch(TrybPracy)
			{
				#ifdef DozwolonaStalaPredkosc
					case StalaPredkosc:
						MOTOR_command(Kierunek);
						MOTOR_command(START);
						while(TrybPracy == StalaPredkosc)
						{
							if (STEROWANIE_KOMPUTEREM_ison())
								LED_showValue(Predkosc);
							else
								LED_showValue(ADC_value);
							MOTOR_speed();
						}
						break;
				#endif

				#ifdef DozwolonaLosowaJazda
					case LosowaJazda:
						MOTOR_command(Kierunek);
						while(TrybPracy == LosowaJazda)
						{
							int i = rand()%CzasJazdyPlusMinus + CzasJazdy - CzasJazdyPlusMinus;

							MOTOR_command(START);
							MOTOR_speed();
							LED_showBinaryValue(i);
							while (i>0 && TrybPracy == LosowaJazda)
							{
								_delay_ms(1000);
								MOTOR_speed();
								--i;
								LED_showBinaryValue(i);
								
							};
							if (TrybPracy != LosowaJazda) break;
							MOTOR_command(STOP);
							MOTOR_speed();
							i = rand()%CzasPostojuPlusMinus + CzasPostoju - CzasPostojuPlusMinus;
							LED_showBinaryValue(i);
							while (i>0 && TrybPracy == LosowaJazda)
							{
								_delay_ms(1000);
								MOTOR_speed();
								--i;
								LED_showBinaryValue(i);
							};
						}
						break;
				#endif

				#ifdef DozwolonyDuzyTor
					case DuzyTor:
						_delay_ms(10000);
						MOTOR_command(Kierunek);
						MOTOR_command(START);
						while(INPUT_isoff(1) && TrybPracy == DuzyTor)
						{ 
							MOTOR_speed();
							sleep();
						}
						unsigned char nrFigurki = 0;
						unsigned char jezyk = 0;
						while(TrybPracy == DuzyTor)
						{
							MOTOR_command(STOP);
							MOTOR_speed();
							if (INPUT_ison(1))
							{
								nrFigurki = 0;
								LED_showBinaryValue(nrFigurki);
								jezyk = (jezyk + 1)%3;
							}
							//Odtwarzanie MP3
							char q = 0;
							
							USART_writeString(komenda_poczatek);
							switch(jezyk)
							{
								case 1:
									q = dlugosciPL[nrFigurki];
									USART_writeString("pl");
									break;
								case 2:
									q = dlugosciEN[nrFigurki];
									USART_writeString("en");
									break;
								case 0:
									q = dlugosciFR[nrFigurki];
									USART_writeString("fr");
									break;
								default:
									LED_Alarm();
									break;
							}
							USART_write(nrFigurki + 1 + '0');
							
							USART_writeString(komenda_koniec);		

							q += 1;
							for (; q >0; --q)
							{
								_delay_ms(1000);
								LED_showBinaryValue(q);
							}
							nrFigurki++;
							if (nrFigurki > 6) nrFigurki = 6;
							//Zjezdzamy z krancowki
							MOTOR_command(START);
							MOTOR_speed();
							_delay_ms(3000);
							while((INPUT_isoff(2) && INPUT_isoff(1)) && TrybPracy == DuzyTor)
							{
								MOTOR_speed(Predkosc);
								sleep();
							}
						}
					break;
				#endif

				#ifdef DozwolonaGwiazda
					case Gwiazda:
					{
						int opoznienie = 6000;
						//unsigned char licznik = 0;
						unsigned char mnoznik = 0;

						//dOpoznienie = 6000 (zakres opoznien) / 100(przejsc przez 0/s) / czas jazdy w [s]
						//MOTOR_command(START);
						//MOTOR_speed(Predkosc);
						unsigned char Rozjasnianie = 1;
						while(TrybPracy == Gwiazda)
						{
							//randOpoznienie = rand()%(dOpoznienie - dOpoznieniePlusMinus) + dOpoznieniePlusMinus;
							while((Rozjasnianie == 1 && opoznienie > dOpoznienie) ||
								 (Rozjasnianie == 0 && opoznienie < 6000))
							{
								if (WykryteZero)
								{
									_delay_us(opoznienie+2000);
									TRIAK_on();
									mnoznik++;
									if (mnoznik == 10)
									{
										mnoznik = 0;
										if (Rozjasnianie)
										{
											opoznienie -= dOpoznienie;
											if (opoznienie < dOpoznienie) 
												opoznienie = dOpoznienie;
										}
										else //sciemnianie
										{
											opoznienie += dOpoznienie;
											if (opoznienie > 6000) opoznienie = 6000;
										}
									}
									while(WykryteZero){ sleep(); }
									_delay_us(100);
									TRIAK_off();
								}
							}
							if (Rozjasnianie == 1)
							{
								Rozjasnianie = 0;
								opoznienie = 0;
							}
							else
							{
								Rozjasnianie = 1;
								opoznienie = 6000;
							}
							/*while(licznik < 100)
							{
								if (WykryteZero)
								{
									_delay_us(opoznienie+2000);
									TRIAK_on();
									licznik++;
									mnoznik++;
									if (mnoznik == 10)
									{
										mnoznik = 0;
										if (Rozjasnianie)
										{
											opoznienie -= dOpoznienie;
											if (opoznienie < dOpoznienie) 
												opoznienie = dOpoznienie;
										}
										else //sciemnianie
										{
											opoznienie += dOpoznienie;
											if (opoznienie > 6000) opoznienie = 6000;
										}
									}
									while(WykryteZero){ sleep(); }
									_delay_us(100);
									TRIAK_off();
								}
							}
							licznik = 0;*/
						}
						break;
				}
				#endif

				default:
					LED_Alarm();
					break;
			};
		#endif
	/* ******************** -------- ******************** */
		#if TRYB == 3
			if (INPUT_ison(1)) 	LED_on(1);
			if (INPUT_isoff(1))	LED_off(1);
			if (INPUT_ison(2))	LED_on(2);
			if (INPUT_isoff(2)) LED_off(2);
			if (INPUT_ison(3))	LED_on(3);
			if (INPUT_isoff(3))	LED_off(3);
		#endif

	/* ******************** -------- ******************** */
		#if TRYB == 2
			LED_showBinaryValue(USART_recv-'0');
			USART_write(USART_recv);
		#endif
	/* ******************** -------- ******************** */
		#if TRYB == 1
			unsigned char i = 0;
			unsigned char value = 3;
			for (i=0; i<8; ++i)
			{
				value = EEPROM_read(i);
				LED_showBinaryValue(value);
				_delay_ms(1000);
			}
		#endif
	/* ******************** -------- ******************** */
		#if TRYB == 0		
			LED_showValue(ADC_value);
			MOTOR_speed(ADC_value);

			if (BUTTON_ison(1))
				MOTOR_command(START); else MOTOR_command(STOP);
	
			if (BUTTON_isoff(2))
				MOTOR_command(GOLEFT); else MOTOR_command(GORIGHT);
		#endif
	/* ******************** -------- ******************** */

	}
	return 0;
}
